<?php
namespace Twoir\System\Support;

/**
 * 单个表处理方式 集合方法
 * cighsen02 qq 365182575
 * time：2022.10.26
 * update: 2025.01.22
*/
trait SingleTrait
{
    /**
     * 字段默认值类型
     *
     * @return array
    */
    public static function fieldType(): array
    {
        $default = static::MYDEFAULT;

        //字段类型
        array_walk($default, function(&$value){

            $value = null === $value || 0 === $value ? 'int' : 'string';

        });

        return $default;
    }

    /**
	 * 数量统计
	 * @param array $where = {key => val},
	 * @return int
	 */
	public static function getCount(array $where = []): int
	{
		global $empire, $dbtbpre;

		['where' => $str_where] = static::parseWhere($where, false);

		$sql = sprintf('SELECT count(*) as total FROM %s%s', $dbtbpre . static::TABLE, $str_where);

		//是否有记录
		return (int)$empire->gettotal($sql);
	}

	/**
	 * 分组数量统计
	 * @param array $where = {key => val},
	 * @param string $group 分组关键字
	 * @return int
	 */
	public static function getGroupCount(array $where, string $group): array
	{
		global $empire, $dbtbpre;

		['where' => $str_where] = static::parseWhere($where, false);

		$sql = sprintf('SELECT `' . $group . '`,count(`' . $group . '`) as total FROM %s%s%s', $dbtbpre . static::TABLE, $str_where, ' GROUP BY `' . $group . '`');

		$sql = $empire->query($sql);

		$res = [];

		if(0 < $empire->num1($sql)){

		    while($r = $empire->fetch($sql)){
		        //去数字键
		        $res[$r[$group]] = array_filter($r, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
		    }
		}

		return $res;
	}

	/**
	 * 读取当条信息
	 *
	 * @param array $where = {key => val}, array $field = {item,item2}
	 * @param array $field 调取的字段
	 * @param string $orderby
	 * @param string $groupby
	 * @return array
	 */
	public static function getOne(array $where = [], array $field = ['*'], string $groupby = '', string $orderby = ''): array
	{
	    $res = static::getList($where, $field, $orderby, $groupby, 1, 0);

	    return $res[0] ?? [];
	}

	/**
	 * 读取多条(列表)
	 *
	 * @param array $where  条件
	 * @param array $field 调取的字段
	 * @param string $orderby
	 * @param string $groupby
	 * @param int $limit
	 * @param int $pagesize
	 * @param int $page
	 * @return array
	 */
	 public static function getList(array $where = [], array $field = ['*'], string $groupby = '', string $orderby = '', int $limit = 0, int $pagesize = 10, int $page = 0): array
	 {
        global $empire, $dbtbpre;

		['where' => $str_where] = static::parseWhere($where, false);

        $get_field  = ['*'] === $field ? static::FIELD : array_intersect(static::FIELD, $field);

        $sql = sprintf('SELECT %s FROM %s%s%s%s%s',
			'`' . implode('`,`', $get_field) . '`',
			$dbtbpre . static::TABLE,
			$str_where,
			null === $groupby || '' === $groupby ? '' : ' GROUP BY ' . $groupby,
			null === $orderby || '' === $orderby ? '' : ' ORDER BY ' . $orderby,
			0 === $limit && 0 === $pagesize ? '' : ($limit > 0 ? ' LIMIT ' . $limit : ' LIMIT ' . ($page * $pagesize) . ',' . $pagesize)
		);

		$sql = $empire->query($sql);
		$res = [];

	    if(0 < $empire->num1($sql)){

            while($r = $empire->fetch($sql)){
                //去数字键
                $res[] = array_filter($r, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
            }
	    }

	    return $res;
	 }


	/**
	 * 插入交易信息
	 *
	 * @param array $add
	 * @return int|true 失败0 成功返回id，无主键时成功返回 true
	 */
	public static function insert(array $add = []): int|bool
	{
		global $empire, $dbtbpre;

		if (empty($add) || !is_array($add)) return 0;

		//过滤无关参数 0不过虑，所有没有 empty
		$add    = array_filter($add, fn($value, $key) => in_array($key, static::FIELD) && (null !== $value || '' !== $value), ARRAY_FILTER_USE_BOTH);
		//更新值
		$add    = array_replace(static::MYDEFAULT, $add);
		['key' => $str_key, 'value' => $str_value] = static::parseInsert($add);

		$str_sql= sprintf('INSERT INTO %s (%s) VALUES (%s)',
			$dbtbpre . static::TABLE,
			$str_key,
			$str_value
		);

		$result	= $empire->query($str_sql);

		return $result ? (static::PRIMARY ? $empire->lastid() : true) : 0;
    }

    /**
	 * 更新数据
	 *
	 * @param array $where
	 * @param array $add
	 * @param int $limit
	 * @return bool
	 **/
	public static function update(array $where = [], array $add = [], int $limit = 0): bool
	{
	    global $empire, $dbtbpre;

		['where' => $str_where] = static::parseWhere($where, false);

	    //去null值, 0值或负值不能去，
	    $add    = array_filter($add, fn($item) => null !== $item);
	    //找出要新字段进行更新
		$update = array_intersect(static::FIELD, array_keys($add));

		$update_data = array_filter($add, fn($item) => in_array($item, $update), ARRAY_FILTER_USE_KEY);

		$sql = sprintf('UPDATE %s SET %s%s%s',
			$dbtbpre . static::TABLE,
			static::parseUpdate($update_data),
			$str_where,
			$limit > 0 ? ' LIMIT ' . $limit : ''
		);

	    return $empire->query($sql);
	}

    /**
     * 删除数据
     *
     * @param array $where
     * @param int $limit
     * @param string $orderby
     * @return bool
    */
    public static function delete(array $where = [], int $limit = 0, string $orderby = ''): bool
    {
        global $empire, $dbtbpre;

		['where' => $str_where] = static::parseWhere($where, false);

	 	$sql = sprintf('DELETE FROM %s%s%s%s',
			$dbtbpre . static::TABLE,
			$str_where,
			null === $orderby || '' === $orderby ? '' : ' ORDER BY ' . $orderby,
			$limit > 0 ? ' limit ' . $limit : ''
		);

        return false !== $empire->query($sql);
    }
}
